#include "EpilExpressionStatementParser.h"
#include "EpilPrimaryExpressionParser.h"
#include "EpilAssignStatementParser.h"
#include "EpilAssignStatementCode.h"
#include "EpilFunctionCallExpressionCode.h"
#include "EpilMethodCallExpressionCode.h"
#include "EpilFunctionCallStatementCode.h"
#include "EpilPointerHelper.h"


EpilExpressionStatementParser::EpilExpressionStatementParser( EpilTokenStream & tokens )
: EpilSyntaxParserBase( tokens )
{
}


void EpilExpressionStatementParser::Parse()
{
	// stat -> func | assignment

	EpilPrimaryExpressionParser primaryExprParser( this->GetTokens() );
	primaryExprParser.Parse();
	EpilExpressionCodeBase * headExpr = primaryExprParser.GetExpression();

	if( headExpr->GetType() == ECT_FunctionCallExpression ||
		headExpr->GetType() == ECT_MethodCallExpression )
	{
		EpilFunctionCallExpressionCodeBase * callExpr = static_cast<EpilFunctionCallExpressionCodeBase*>( headExpr );
		EpilFunctionCallStatementCode * funcCallStat = new EpilFunctionCallStatementCode( callExpr->GetLocation() );
		funcCallStat->SetExpression( callExpr );
		m_statement = funcCallStat;
		return;
	}

	EpilAssignStatementParser assignStatParser( this->GetTokens() );
	try
	{
		assignStatParser.Parse();
	}
	catch( ... )
	{
		EpilPointerHelper::SafeDelete( headExpr );
		throw;
	}

	EpilExpressionCodeList & assigners = assignStatParser.GetAssigners();
	EpilExpressionCodeList assignees = assignStatParser.GetAssignees();
	assignees.push_front( headExpr );

	EpilAssignStatementCode * assignStat = new EpilAssignStatementCode( headExpr->GetLocation() );
	assignStat->SetAssignees( assignees );
	assignStat->SetAssigners( assigners );
	m_statement = assignStat;
}